package client

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/user/linux-command/utils"
	"io"
	"net/http"
	"time"

	"github.com/user/linux-command/database"
	"github.com/user/linux-command/models"
)

// JSONRPCClient JSON-RPC客户端
type JSONRPCClient struct {
	BaseURL string
	Client  *http.Client
}

// NewJSONRPCClient 创建新的JSON-RPC客户端
func NewJSONRPCClient(baseURL string) *JSONRPCClient {
	return &JSONRPCClient{
		BaseURL: baseURL,
		Client: &http.Client{
			Timeout: 30 * time.Second,
		},
	}
}

// Call 执行JSON-RPC调用
func (c *JSONRPCClient) Call(method string, params interface{}) (*models.JSONRPCResponse, error) {
	request := models.JSONRPCRequest{
		JSONRPC: "2.0",
		Method:  method,
		Params:  params,
		ID:      1,
	}

	requestBody, err := json.Marshal(request)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal request: %v", err)
	}

	req, err := http.NewRequest("POST", c.BaseURL, bytes.NewBuffer(requestBody))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", "application/json, text/event-stream")
	resp, err := c.Client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to send request: %v", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read response: %v", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("unexpected status url: %v code: %d body: %v reuqest: %v", c.BaseURL, resp.StatusCode, string(body), string(requestBody))
	}
	//这里清洗数据
	b1 := string(body)
	b1 = utils.ExtractJSON(b1)

	var response models.JSONRPCResponse
	if err := json.Unmarshal([]byte(b1), &response); err != nil {
		return nil, fmt.Errorf(" failed to unmarshal response: %v code: %d body: %v reuqest: %v", c.BaseURL, resp.StatusCode, string(body), string(requestBody))
	}

	return &response, nil
}

// GetTools 调用tools/list方法获取工具列表
func (c *JSONRPCClient) GetTools() (*models.ToolListResponse, error) {
	response, err := c.Call("tools/list", nil)
	if err != nil {
		return nil, err
	}

	if response.Error != nil {
		return nil, fmt.Errorf("RPC error: %s (code: %d)", response.Error.Message, response.Error.Code)
	}

	// 解析结果
	var toolList models.ToolListResponse
	resultJSON, err := json.Marshal(response.Result)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal result: %v", err)
	}

	if err := json.Unmarshal(resultJSON, &toolList); err != nil {
		return nil, fmt.Errorf("failed to unmarshal tool list: %v", err)
	}

	return &toolList, nil
}

// RegisterService 注册MCP服务并获取工具列表
func RegisterService(name, url, description string) error {
	// 创建服务
	service := &models.MCPService{
		Name:        name,
		URL:         url,
		Description: description,
		IsActive:    true,
	}

	// 保存服务到数据库
	if err := database.CreateService(service); err != nil {
		return fmt.Errorf("failed to create service: %v", err)
	}

	// 获取工具列表
	client := NewJSONRPCClient(url)
	toolList, err := client.GetTools()
	if err != nil {
		// 如果获取工具失败，删除服务
		database.DeleteService(service.ID)
		return fmt.Errorf("failed to get tools from service: %v", err)
	}

	// 保存工具到数据库
	for _, toolDef := range toolList.Tools {
		tool := &models.MCPTool{
			ServiceID:   service.ID,
			Name:        toolDef.Name,
			Description: toolDef.Description,
			InputSchema: toolDef.InputSchema,
		}

		if err := database.CreateTool(tool); err != nil {
			// 记录错误但继续处理其他工具
			fmt.Printf("Failed to create tool %s: %v\n", toolDef.Name, err)
		}
	}

	return nil
}
